﻿using System;
using System.Diagnostics;
using System.IO;

namespace AutoBuild.Core.Framework
{
    /// <summary>
    /// Executes a process specified by the <see cref="ProcessStartInfo"/> object passed int the <see cref="Execute"/> method.
    /// Execptions are caugth an logged to the <see cref="IConsole"/> passed on construction.
    /// </summary>
    public class ProcessExecutor : IProcessExecutor
    {
        //---- Members -----------------------------------------------------
        private readonly IConsole _console;

        //---------------------------------------------------------
        public ProcessExecutor(IConsole console)
        {
            _console = console;
        }

        //---------------------------------------------------------
        public void Execute(ProcessStartInfo startInfo)
        {
            Execute(startInfo, false);
        }

        //---------------------------------------------------------
        public void Execute(ProcessStartInfo startInfo, bool raiseException )
        {
            Process process = null;
            if ((startInfo.RedirectStandardOutput || startInfo.RedirectStandardError) && startInfo.UseShellExecute)
            {
                throw new InvalidOperationException(
                    "The Process object must have the UseShellExecute property set to false in order to redirect IO streams.");
            }
            try
            {
                process = new Process
                                      {
                                          StartInfo = startInfo
                                      };
                process.Start();                
                process.WaitForExit();
                
            }
            catch (Exception ex)
            {
                _console.Error("Error starting build process", ex);
                if (raiseException)
                {
                    throw;
                }
            }
            finally
            {
                if (process != null)
                {
                    if (startInfo.RedirectStandardOutput)
                    {
                        var output = process.StandardOutput.ReadToEnd();
                        _console.Info(output);
                    }
                    if (startInfo.RedirectStandardError)
                    {
                        var output = process.StandardError.ReadToEnd();
                        _console.Error(output);
                    }
                    process.Close();
                }                
            }


        }

    }
}